package com.ssy.lingxi.logistics.serviceimpl;

import cn.hutool.core.util.StrUtil;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.logistics.entity.ReceiverAddress;
import com.ssy.lingxi.logistics.entity.ShipperAddress;
import com.ssy.lingxi.logistics.model.enums.CommonBooleanEnum;
import com.ssy.lingxi.logistics.model.request.StoreShipperAddressListRequest;
import com.ssy.lingxi.logistics.model.response.mobile.MobileShipperAddressListResponse;
import com.ssy.lingxi.logistics.model.response.mobile.MobileStoreShipperAddressListResponse;
import com.ssy.lingxi.logistics.repository.ReceiverAddressRepository;
import com.ssy.lingxi.logistics.repository.ShipperAddressRepository;
import com.ssy.lingxi.logistics.service.IMobileShipperAddressService;
import com.ssy.lingxi.logistics.util.LogisticsAddressUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * app发货地址服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2020/7/13
 */
@Service
public class MobileShipperAddressServiceImpl implements IMobileShipperAddressService {

    @Resource
    private ShipperAddressRepository shipperAddressRepository;
    @Resource
    private ReceiverAddressRepository receiverAddressRepository;


    @Override
    public Wrapper<PageData<MobileShipperAddressListResponse>> pageShipperAddress(PageVO request, UserLoginCacheDTO loginUser) {
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("id").ascending());

        Specification<ShipperAddress> specification = buildSpecification(loginUser.getMemberId(), loginUser.getMemberRoleId());
        Page<ShipperAddress> pageList = shipperAddressRepository.findAll(specification, page);

        // 组装数据
        List<MobileShipperAddressListResponse> resultList = convertAddressResponse(pageList.getContent());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<List<MobileShipperAddressListResponse>> listShipperAddressDefault(UserLoginCacheDTO loginUser) {
        Sort sort = Sort.by("createTime").descending();
        Specification<ShipperAddress> specification = buildSpecification(loginUser.getMemberId(), loginUser.getMemberRoleId());
        List<ShipperAddress> shipperAddressList = shipperAddressRepository.findAll(specification, sort);

        // 默认地址首位
        List<ShipperAddress> handleList = new ArrayList<>();
        Iterator<ShipperAddress> iterator = shipperAddressList.iterator();
        while (iterator.hasNext()) {
            ShipperAddress next = iterator.next();
            if (CommonBooleanEnum.YES.getCode().equals(next.getIsDefault())) {
                handleList.add(next);
                iterator.remove();
                break;
            }
        }
        handleList.addAll(shipperAddressList);

        // 组装数据
        List<MobileShipperAddressListResponse> resultList = convertAddressResponse(handleList);

        return Wrapper.success(resultList);
    }

    private Specification<ShipperAddress> buildSpecification(Long memberId, Long roleId) {
        return (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("memberId"), memberId));
            predicateList.add(cb.equal(root.get("roleId"), roleId));

            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        };
    }

    private List<MobileShipperAddressListResponse> convertAddressResponse(List<ShipperAddress> addressList) {
        return addressList.stream().map(e -> {
            MobileShipperAddressListResponse shipperAddressListResponse = new MobileShipperAddressListResponse();
            shipperAddressListResponse.setId(e.getId());
            shipperAddressListResponse.setShipperName(e.getShipperName());
            shipperAddressListResponse.setProvinceName(e.getProvinceName());
            shipperAddressListResponse.setCityName(e.getCityName());
            shipperAddressListResponse.setDistrictName(e.getDistrictName());
            shipperAddressListResponse.setStreetCode(StrUtil.isEmpty(e.getStreetCode()) ? "" : e.getStreetCode());
            shipperAddressListResponse.setStreetName(StrUtil.isEmpty(e.getStreetName()) ? "" : e.getStreetName());
            shipperAddressListResponse.setAddress(e.getAddress());
            shipperAddressListResponse.setPostalCode(e.getPostalCode());
            shipperAddressListResponse.setPhone(e.getPhone());
            shipperAddressListResponse.setTel(e.getTel());
            shipperAddressListResponse.setIsDefault(e.getIsDefault());
            return shipperAddressListResponse;
        }).collect(Collectors.toList());
    }

    /**
     * 门店发货地址列表
     * @param request 接口参数
     * @return 返回结果
     */
    public Wrapper<List<MobileStoreShipperAddressListResponse>> storeShipperAddressList(StoreShipperAddressListRequest request) {
        List<ShipperAddress> storeAddressList = shipperAddressRepository.findAllByMemberIdAndRoleIdAndStoreStatus(request.getVendorMemberId(), request.getVendorRoleId(), CommonBooleanEnum.YES.getCode(), Sort.by("id").descending());


        List<MobileStoreShipperAddressListResponse> responseList = new ArrayList<>();

        List<MobileStoreShipperAddressListResponse> resultList = storeAddressList.stream()
                .map(e -> {
                    MobileStoreShipperAddressListResponse addressListResponse = new MobileStoreShipperAddressListResponse();
                    addressListResponse.setId(e.getId());
                    addressListResponse.setStoreId(e.getStoreId());
                    addressListResponse.setShipperName(e.getShipperName());
                    addressListResponse.setProvinceCode(e.getProvinceCode());
                    addressListResponse.setProvinceName(e.getProvinceName());
                    addressListResponse.setCityCode(e.getCityCode());
                    addressListResponse.setCityName(e.getCityName());
                    addressListResponse.setDistrictCode(e.getDistrictCode());
                    addressListResponse.setDistrictName(e.getDistrictName());
                    addressListResponse.setStreetCode(e.getStreetCode());
                    addressListResponse.setStreetName(e.getStreetName());
                    addressListResponse.setAddress(e.getAddress());
                    addressListResponse.setPostalCode(e.getPostalCode());
                    addressListResponse.setPhone(e.getPhone());
                    addressListResponse.setTel(e.getTel());
                    addressListResponse.setIsDefault(e.getIsDefault());
                    addressListResponse.setStoreName(StrUtil.isEmpty(e.getStoreName()) ? "" : e.getStoreName());
                    // 拼接完整的地址
                    String fullAddress = LogisticsAddressUtil.contractFullAddress(e.getProvinceName(), e.getCityName(), e.getDistrictName(), e.getStreetName(), e.getAddress());
                    addressListResponse.setFullAddress(fullAddress);
                    return addressListResponse;
                }).collect(Collectors.toList());

        if (request.getReceiveId() != null) {
            ReceiverAddress receiverAddress = receiverAddressRepository.findById(request.getReceiveId()).orElse(null);
            if (receiverAddress != null) {
                String pro = StringUtils.isNotEmpty(receiverAddress.getPostalCode()) ? receiverAddress.getPostalCode() : "";
                String cit = StringUtils.isNotEmpty(receiverAddress.getCityCode()) ? receiverAddress.getCityCode() : "";
                String dis = StringUtils.isNotEmpty(receiverAddress.getDistrictCode()) ? receiverAddress.getDistrictCode() : "";
                String str = StringUtils.isNotEmpty(receiverAddress.getStreetCode()) ? receiverAddress.getStreetCode() : "";

                List<MobileStoreShipperAddressListResponse> proList = resultList.stream().filter(v -> StrUtil.isNotEmpty(v.getPostalCode()) && v.getPostalCode().equals(pro)).collect(Collectors.toList());
                List<MobileStoreShipperAddressListResponse> citList = resultList.stream().filter(v -> StrUtil.isNotEmpty(v.getCityCode()) && v.getCityCode().equals(cit)).collect(Collectors.toList());
                List<MobileStoreShipperAddressListResponse> disList = resultList.stream().filter(v -> StrUtil.isNotEmpty(v.getDistrictCode()) && v.getDistrictCode().equals(dis)).collect(Collectors.toList());
                List<MobileStoreShipperAddressListResponse> strList = resultList.stream().filter(v -> StrUtil.isNotEmpty(v.getStreetCode()) && v.getStreetCode().equals(str)).collect(Collectors.toList());

                responseList.addAll(strList);
                responseList.addAll(disList);
                responseList.addAll(citList);
                responseList.addAll(proList);
                responseList.addAll(resultList);
            }
        } else {
            responseList.addAll(resultList);
        }

        return Wrapper.success(responseList.stream().distinct().collect(Collectors.toList()));
    }
}